package com.ihome.android.util;

import java.lang.reflect.Field;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.view.View;

import com.ihome.android.annotation.EAInject;
import com.ihome.android.annotation.EAInjectResource;
import com.ihome.android.annotation.EAInjectView;


public class EAInjector {
	private static EAInjector	instance;

	private EAInjector() {

	}

	public static EAInjector getInstance() {
		if (instance == null) {
			instance = new EAInjector();
		}
		return instance;
	}

	public void inJectAll(Activity activity) {

		Field[] fields = activity.getClass().getDeclaredFields();
		if (fields != null && fields.length > 0) {
			for (Field field : fields) {
				if (field.isAnnotationPresent(EAInjectView.class)) {
					injectView(activity, field);
				}
				else if (field.isAnnotationPresent(EAInjectResource.class)) {
					injectResource(activity, field);
				}
				else if (field.isAnnotationPresent(EAInject.class)) {
					inject(activity, field);
				}
			}
		}
	}

	private void inject(Activity activity, Field field) {

		try {
			field.setAccessible(true);
			field.set(activity, field.getType().newInstance());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void injectView(Activity activity, Field field) {

		if (field.isAnnotationPresent(EAInjectView.class)) {
			EAInjectView viewInject = field.getAnnotation(EAInjectView.class);
			int viewId = viewInject.id();
			try {
				field.setAccessible(true);
				//activity.fieldName = value;
				field.set(activity, activity.findViewById(viewId));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private void injectResource(Activity activity, Field field) {

		if (field.isAnnotationPresent(EAInjectResource.class)) {
			EAInjectResource resourceJect = field.getAnnotation(EAInjectResource.class);
			int resourceID = resourceJect.id();
			try {
				field.setAccessible(true);
				Resources resources = activity.getResources();
				String type = resources.getResourceTypeName(resourceID);
				if (type.equalsIgnoreCase("string")) {
					field.set(activity, activity.getResources().getString(resourceID));
				}
				else if (type.equalsIgnoreCase("drawable")) {
					field.set(activity, activity.getResources().getDrawable(resourceID));
				}
				else if (type.equalsIgnoreCase("layout")) {
					field.set(activity, activity.getResources().getLayout(resourceID));
				}
				else if (type.equalsIgnoreCase("array")) {
					if (field.getType().equals(int[].class)) {
						field.set(activity, activity.getResources().getIntArray(resourceID));
					}
					else if (field.getType().equals(String[].class)) {
						field.set(activity, activity.getResources().getStringArray(resourceID));
					}
					else {
						field.set(activity, activity.getResources().getStringArray(resourceID));
					}

				}
				else if (type.equalsIgnoreCase("color")) {
					if (field.getType().equals(Integer.TYPE)) {
						field.set(activity, activity.getResources().getColor(resourceID));
					}
					else {
						field.set(activity, activity.getResources().getColorStateList(resourceID));
					}

				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public <T> void inJectAll(T mViewHolder, View view) {

		Field[] fields = mViewHolder.getClass().getDeclaredFields();
		if (fields != null && fields.length > 0) {
			for (Field field : fields) {
				if (field.isAnnotationPresent(EAInjectView.class)) {
					injectView(mViewHolder, view, field);
				}
				else if (field.isAnnotationPresent(EAInjectResource.class)) {
					injectResource(mViewHolder, view, field);
				}
				else if (field.isAnnotationPresent(EAInject.class)) {
					inject(mViewHolder, field);
				}
			}
		}
	}

	private <T> void inject(T mViewHolder, Field field) {

		try {
			field.setAccessible(true);
			field.set(mViewHolder, field.getType().newInstance());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private <T> void injectView(T mViewHolder, View view, Field field) {

		if (field.isAnnotationPresent(EAInjectView.class)) {
			EAInjectView viewInject = field.getAnnotation(EAInjectView.class);
			int viewId = viewInject.id();
			try {
				field.setAccessible(true);
				field.set(mViewHolder, view.findViewById(viewId));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private <T> void injectResource(T mViewHolder, View view, Field field) {

		if (field.isAnnotationPresent(EAInjectResource.class)) {
			EAInjectResource resourceJect = field.getAnnotation(EAInjectResource.class);
			int resourceID = resourceJect.id();
			try {
				field.setAccessible(true);
				Context context = view.getContext();
				Resources resources = context.getResources();
				String type = resources.getResourceTypeName(resourceID);
				if (type.equalsIgnoreCase("string")) {
					field.set(mViewHolder, context.getResources().getString(resourceID));
				}
				else if (type.equalsIgnoreCase("drawable")) {
					field.set(mViewHolder, context.getResources().getDrawable(resourceID));
				}
				else if (type.equalsIgnoreCase("layout")) {
					field.set(mViewHolder, context.getResources().getLayout(resourceID));
				}
				else if (type.equalsIgnoreCase("array")) {
					if (field.getType().equals(int[].class)) {
						field.set(mViewHolder, context.getResources().getIntArray(resourceID));
					}
					else if (field.getType().equals(String[].class)) {
						field.set(mViewHolder, context.getResources().getStringArray(resourceID));
					}
					else {
						field.set(mViewHolder, context.getResources().getStringArray(resourceID));
					}

				}
				else if (type.equalsIgnoreCase("color")) {
					if (field.getType().equals(Integer.TYPE)) {
						field.set(mViewHolder, context.getResources().getColor(resourceID));
					}
					else {
						field.set(mViewHolder, context.getResources().getColorStateList(resourceID));
					}

				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public void inject(Activity activity) {

		Field[] fields = activity.getClass().getDeclaredFields();
		if (fields != null && fields.length > 0) {
			for (Field field : fields) {
				if (field.isAnnotationPresent(EAInject.class)) {
					inject(activity, field);
				}
			}
		}
	}

	public <T> void inject(T mViewHolder) {

		Field[] fields = mViewHolder.getClass().getDeclaredFields();
		if (fields != null && fields.length > 0) {
			for (Field field : fields) {
				if (field.isAnnotationPresent(EAInject.class)) {
					inject(mViewHolder, field);
				}
			}
		}
	}

	public void injectView(Activity activity) {

		Field[] fields = activity.getClass().getDeclaredFields();
		if (fields != null && fields.length > 0) {
			for (Field field : fields) {
				if (field.isAnnotationPresent(EAInjectView.class)) {
					injectView(activity, field);
				}
			}
		}
	}

	public <T> void injectView(T mViewHolder, View view) {

		Field[] fields = mViewHolder.getClass().getDeclaredFields();
		if (fields != null && fields.length > 0) {
			for (Field field : fields) {
				if (field.isAnnotationPresent(EAInjectView.class)) {
					injectView(mViewHolder, view, field);
				}
			}
		}
	}

	public void injectResource(Activity activity) {

		Field[] fields = activity.getClass().getDeclaredFields();
		if (fields != null && fields.length > 0) {
			for (Field field : fields) {
				if (field.isAnnotationPresent(EAInjectResource.class)) {
					injectResource(activity, field);
				}
			}
		}
	}

	public <T> void injectResource(T mViewHolder, View view) {

		Field[] fields = mViewHolder.getClass().getDeclaredFields();
		if (fields != null && fields.length > 0) {
			for (Field field : fields) {
				if (field.isAnnotationPresent(EAInjectResource.class)) {
					injectResource(mViewHolder, view, field);
				}
			}
		}
	}

}
